package com.vader.common.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ZipUtil;
import com.vader.common.entity.DO.ColumnInfoDO;
import com.vader.common.entity.DO.GeneratorConfigDO;
import com.vader.common.exception.BadRequestException;
import com.vader.common.mapper.ColumnConfigMapper;
import com.vader.common.utils.FileUtil;
import com.vader.common.utils.GeneratorUtil;
import com.vader.common.utils.StringUtils;
import com.vader.common.service.GeneratorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Vader
 * @date 2021/10/5
 **/
@Service
public class GeneratorServiceImpl implements GeneratorService {

    private static final Logger log = LoggerFactory.getLogger(GeneratorServiceImpl.class);

    @Resource
    private ColumnConfigMapper columnConfigMapper;

    @Override
    public Object getTables() {
        return columnConfigMapper.getTables();
    }

    @Override
    public Object getTables(String name, int[] startEnd) {
        int count = columnConfigMapper.getTablesCount(name);
        if (count < 1) {
            return null;
        }

        return columnConfigMapper.getTablesByName(name);
    }

    @Override
    public List<ColumnInfoDO> getColumns(String name) {
        List<ColumnInfoDO> columnInfos = columnConfigMapper.findByTableNameOrderByIdAsc(name);
        if (CollectionUtil.isNotEmpty(columnInfos)) {
            return columnInfos;
        } else {
            columnInfos = query(name);
            int i = columnConfigMapper.insertAll(columnInfos);
            if (i != columnInfos.size()) {
                throw new RuntimeException("插入出错");
            }
            return columnInfos;
        }
    }

    @Override
    public void sync(List<ColumnInfoDO> columnInfoList, List<ColumnInfoDO> columnInfoDOList) {
        // 第一种情况，数据库类字段改变或者新增字段
        for (ColumnInfoDO columnInfo : columnInfoList) {
            // 根据字段名称查找
            List<ColumnInfoDO> columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList());
            // 如果能找到，就修改部分可能被字段
            if (CollectionUtil.isNotEmpty(columns)) {
                ColumnInfoDO column = columns.get(0);
                column.setColumnType(columnInfo.getColumnType());
                column.setExtra(columnInfo.getExtra());
                column.setKeyType(columnInfo.getKeyType());
                if (StringUtils.isBlank(column.getRemark())) {
                    column.setRemark(columnInfo.getRemark());
                }
                columnConfigMapper.update(column);
            } else {
                // 如果找不到，则保存新字段信息
                columnConfigMapper.insert(columnInfo);
            }
        }
        // 第二种情况，数据库字段删除了
        for (ColumnInfoDO columnInfo : columnInfoList) {
            // 根据字段名称查找
            List<ColumnInfoDO> columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList());
            // 如果找不到，就代表字段被删除了，则需要删除该字段
            if (CollectionUtil.isEmpty(columns)) {
                columnConfigMapper.delete(columnInfo);
            }
        }
    }

    @Override
    public int insertAll(List<ColumnInfoDO> columnInfoList) {
        return columnConfigMapper.insertAll(columnInfoList);
    }

    @Override
    public void generator(GeneratorConfigDO generatorConfigDO, List<ColumnInfoDO> columns) {
        if (generatorConfigDO.getId() == null) {
            throw new BadRequestException("请先配置生成器");
        }
        try {
            GeneratorUtil.generatorCode(columns, generatorConfigDO);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new BadRequestException("生成失败，请手动处理已生成的文件");
        }
    }

    @Override
    public ResponseEntity<Object> preview(GeneratorConfigDO generatorConfigDO, List<ColumnInfoDO> columns) {
        if (generatorConfigDO.getId() == null) {
            throw new BadRequestException("请先配置生成器");
        }
        List<Map<String, Object>> genList = GeneratorUtil.preview(columns, generatorConfigDO);
        return new ResponseEntity<>(genList, HttpStatus.OK);
    }

    @Override
    public void download(GeneratorConfigDO generatorConfigDO, List<ColumnInfoDO> columns, HttpServletRequest request, HttpServletResponse response) {
        if (generatorConfigDO.getId() == null) {
            throw new BadRequestException("请先配置生成器");
        }
        try {
            File file = new File(GeneratorUtil.download(columns, generatorConfigDO));
            String zipPath = file.getPath() + ".zip";
            ZipUtil.zip(file.getPath(), zipPath);
            FileUtil.downloadFile(request, response, new File(zipPath), true);
        } catch (IOException e) {
            throw new BadRequestException("打包失败");
        }
    }

    @Override
    public List<ColumnInfoDO> query(String table) {
        return columnConfigMapper.queryByTableName(table);
    }
}
